package com.carful.xigua.modules.common.filter;


import com.carful.xigua.modules.common.config.SecurityConfig;
import com.carful.xigua.modules.common.util.JwtUtils;
import com.carful.xigua.modules.user.entity.User;
import com.carful.xigua.modules.user.service.impl.UserServiceImpl;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Objects;

@Component // 注册到spring容器就直接加入到 spring的过滤器链
@Slf4j
@Order(1)
public class JwtFilter extends OncePerRequestFilter {

    @Autowired
    private ApplicationContext context;

    @Autowired
    private UserServiceImpl userService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        try {
            log.info(request.getRequestURI() + " " + request.getMethod());
            JwtUtils jwtUtils = context.getBean(JwtUtils.class);
            //  获取 token
            String token = Objects.requireNonNull(jwtUtils.getTokenFromRequest(request), "没有token");
            // 获取 token中 username
            String username = Objects.requireNonNull(jwtUtils.getUserFromToken(token), "错误token");

            // 获取用户
            SecurityConfig.LoginUserDetails userDetails = new SecurityConfig.LoginUserDetails();
            User user1 = userService.selectOne(username);
            if (user1 == null) throw new RuntimeException("token 失效");
            userDetails.setUser(user1);
            userDetails.setAuthorities(userDetails.getUser().getAuthorities());

            // 判断token是否有效
            if (jwtUtils.validateToken(token, userDetails)) {
                // 存入 SecurityContextHolder
                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            }
        } catch (Exception e) {

        }
        chain.doFilter(request, response);
    }
}
